﻿/*
 * 由SharpDevelop创建。
 * 用户： Administrator
 * 日期: 2024/11/30
 * 时间: 1:06
 * 
 * 要改变这种模板请点击 工具|选项|代码编写|编辑标准头文件
 */
using System;
using System.IO;
using System.Linq;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices; 
using Microsoft.Win32;
using System.Diagnostics;
using System.Reflection;

namespace topbar
{
	/// <summary>
	/// Description of MainForm.
	/// </summary>
	public partial class MainForm : Form
	{
		List<Type> types = new List<Type>();
		public MainForm()
		{
			//
			// The InitializeComponent() call is required for Windows Forms designer support.
			//
			InitializeComponent();
		
			//挂在插件第一种方法
			String path = System.Environment.CurrentDirectory+"\\plugin";
			string[] files = Directory.GetFiles(path, "*.dll");
			
			foreach (string file in files)
			{
			   types.Clear();
                Assembly outerAsm = Assembly.LoadFrom(file);
                //反射出dll中的所有类型，加入到下拉框中
                types = outerAsm.GetTypes().ToList();
                types.Reverse();
       
                foreach (var item in types)
                { 
                	var form= (Activator.CreateInstance(item) as Form);//转换成窗体类
                	if (form != null)
	                {
	                    Panel pan=new Panel();
	                	pan.Height=form.Height;
	                	pan.Width=form.Width;
	                	pan.Left=form.Left;
	                	pan.Top=form.Top;
	                	pan.Parent=panel1;
	                    form.TopLevel = false;
	                    form.Dock = DockStyle.Fill;
	                    pan.Controls.Add(form);
	                    form.Show();
	                }
                	
                }
			}
			
			
			
			RegisterBar();//注册topbar
			 
			//设置窗口透明，不透明度205
	        SetWindowTransparent(this.Handle,255);
	        //设置窗口模糊
	      //  SetWindowAero(this.Handle);
			
			string inipath=Directory.GetCurrentDirectory()+"\\setting.ini"; 
			int w=int.Parse(iniHelper.Read("hitokoto","width",inipath));
			string x=((Screen.PrimaryScreen.Bounds.Width-w)/2).ToString();
			iniHelper.Write("hitokoto","left",x,inipath); 
		}
		
	#region	 获取主题色  
   // https://kira-96.github.io/posts/%E5%A6%82%E4%BD%95%E8%8E%B7%E5%8F%96windows10%E4%B8%BB%E9%A2%98%E9%A2%9C%E8%89%B2/
	 // \HKEY_CURRENT_USER\Software\Microsoft\Windows\DWM\ColorizationColor
	public static Color GetColorizationColor()
	{
		if (IsWindowPrevalenceAccentColor()) {
			using (RegistryKey dwm = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\DWM", false))
		    {
		    	if (dwm.GetValueNames().Contains("ColorizationColor"))
		        {
		            int accentColor = (int)dwm.GetValue("ColorizationColor");
		            // 注意：读取到的颜色为 AARRGGBB
		            return Color.FromArgb(
		                (byte)((accentColor >> 24) & 0xFF),
		                (byte)((accentColor >> 16) & 0xFF),
		                (byte)((accentColor >> 8) & 0xFF),
		                (byte)(accentColor & 0xFF));
		        }
		    }
		}
	    
	    return System.Drawing.SystemColors.Control;
	}
	
	// \HKEY_CURRENT_USER\Software\Microsoft\Windows\DWM\ColorPrevalence
	public static bool IsWindowPrevalenceAccentColor()
	{
	    using (RegistryKey dwm = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\DWM", false))
	    {
	        if (dwm.GetValueNames().Contains("ColorPrevalence"))
	        {
	            int colorPrevalence = (int)dwm.GetValue("ColorPrevalence");
	
	            return colorPrevalence == 1;
	        }
	    }
	
	    return false;
	}
	
	#endregion

		#region APPBAR

        [StructLayout(LayoutKind.Sequential)]
        struct RECT
        {
            public int left;
            public int top;
            public int right;
            public int bottom;
        }

        [StructLayout(LayoutKind.Sequential)]
        struct APPBARDATA
        {
            public int cbSize;
            public IntPtr hWnd;
            public int uCallbackMessage;
            public int uEdge;
            public RECT rc;
            public IntPtr lParam;
        }

        enum ABMsg : int
        {
            ABM_NEW=0,
            ABM_REMOVE=1,
            ABM_QUERYPOS=2,
            ABM_SETPOS=3,
            ABM_GETSTATE=4,
            ABM_GETTASKBARPOS=5,
            ABM_ACTIVATE=6,
            ABM_GETAUTOHIDEBAR=7,
            ABM_SETAUTOHIDEBAR=8,
            ABM_WINDOWPOSCHANGED=9,
            ABM_SETSTATE=10
        }

        enum ABNotify : int
        {
            ABN_STATECHANGE=0,
            ABN_POSCHANGED,
            ABN_FULLSCREENAPP,
            ABN_WINDOWARRANGE
        }

        enum ABEdge : int
        {
            ABE_LEFT=0,
            ABE_TOP,
            ABE_RIGHT,
            ABE_BOTTOM
        }

        private bool fBarRegistered = false;

        [DllImport("SHELL32", CallingConvention=CallingConvention.StdCall)]
        static extern uint SHAppBarMessage(int dwMessage, ref APPBARDATA pData);
        [DllImport("USER32")]
        static extern int GetSystemMetrics(int Index);
        [DllImport("User32.dll", ExactSpelling=true, 
            CharSet=System.Runtime.InteropServices.CharSet.Auto)]
        private static extern bool MoveWindow
            (IntPtr hWnd, int x, int y, int cx, int cy, bool repaint);
        [DllImport("User32.dll", CharSet=CharSet.Auto)]
        private static extern int RegisterWindowMessage(string msg);
        private int uCallBack;

        private void RegisterBar()
        {
            APPBARDATA abd = new APPBARDATA();
            abd.cbSize = Marshal.SizeOf(abd);
            abd.hWnd = this.Handle;
            if (!fBarRegistered)
            {
                uCallBack = RegisterWindowMessage("AppBarMessage");
                abd.uCallbackMessage = uCallBack;

                uint ret = SHAppBarMessage((int)ABMsg.ABM_NEW, ref abd);
                fBarRegistered = true;

                ABSetPos();
            }
            else
            {
                SHAppBarMessage((int)ABMsg.ABM_REMOVE, ref abd);
                fBarRegistered = false;
            }
        }
        
        private void ABSetPos()
        {
            APPBARDATA abd = new APPBARDATA();
            abd.cbSize = Marshal.SizeOf(abd);
            abd.hWnd = this.Handle;
            abd.uEdge = (int)ABEdge.ABE_TOP;

            if (abd.uEdge == (int)ABEdge.ABE_LEFT || abd.uEdge == (int)ABEdge.ABE_RIGHT) 
            {
                abd.rc.top = 0;
                abd.rc.bottom = SystemInformation.PrimaryMonitorSize.Height;
                if (abd.uEdge == (int)ABEdge.ABE_LEFT) 
                {
                    abd.rc.left = 0;
                    abd.rc.right = Size.Width;
                }
                else 
                {
                    abd.rc.right = SystemInformation.PrimaryMonitorSize.Width;
                    abd.rc.left = abd.rc.right - Size.Width;
                }

            }
            else 
            {
                abd.rc.left = 0;
                abd.rc.right = SystemInformation.PrimaryMonitorSize.Width;
                if (abd.uEdge == (int)ABEdge.ABE_TOP) 
                {
                    abd.rc.top = 0;
                    abd.rc.bottom = Size.Height;
                }
                else 
                {
                    abd.rc.bottom = SystemInformation.PrimaryMonitorSize.Height;
                    abd.rc.top = abd.rc.bottom - Size.Height;
                }
            }

            // Query the system for an approved size and position. 
            SHAppBarMessage((int)ABMsg.ABM_QUERYPOS, ref abd); 

            // Adjust the rectangle, depending on the edge to which the 
            // appbar is anchored. 
            switch (abd.uEdge) 
            { 
                case (int)ABEdge.ABE_LEFT: 
                    abd.rc.right = abd.rc.left + Size.Width;
                    break; 
                case (int)ABEdge.ABE_RIGHT: 
                    abd.rc.left= abd.rc.right - Size.Width;
                    break; 
                case (int)ABEdge.ABE_TOP: 
                    abd.rc.bottom = abd.rc.top + Size.Height;
                    break; 
                case (int)ABEdge.ABE_BOTTOM: 
                    abd.rc.top = abd.rc.bottom - Size.Height;
                    break; 
            }

            // Pass the final bounding rectangle to the system. 
            SHAppBarMessage((int)ABMsg.ABM_SETPOS, ref abd); 

            // Move and size the appbar so that it conforms to the 
            // bounding rectangle passed to the system. 
            MoveWindow(abd.hWnd, abd.rc.left, abd.rc.top, 
                abd.rc.right - abd.rc.left, abd.rc.bottom - abd.rc.top, true); 
        }

        protected override void WndProc(ref System.Windows.Forms.Message m)
        {
            if (m.Msg == uCallBack)
            {
                switch(m.WParam.ToInt32())
                {
                    case (int)ABNotify.ABN_POSCHANGED:
                        ABSetPos();
                        break;
                }
            }
			try {
				base.WndProc(ref m);
			} catch (Exception) {
				
				 
			}
            
        }

        protected override System.Windows.Forms.CreateParams CreateParams
        {
            get
            {
                CreateParams cp = base.CreateParams;
                cp.Style &= (~0x00C00000); // WS_CAPTION
                cp.Style &= (~0x00800000); // WS_BORDER
                cp.ExStyle = 0x00000080 | 0x00000008; // WS_EX_TOOLWINDOW | WS_EX_TOPMOST
                return cp;
            }
        }
		
        #endregion
        
        #region 模糊
        //https://www.cnblogs.com/sena1418/articles/16141712.html  C# 实现窗口透明模糊效果 
        
        public const int GWL_EXSTYLE = -20;
        public const int LWA_ALPHA = 0x00000002;
        public const int WS_EX_LAYERED = 0x00080000;
        [DllImport("user32.dll")]
        public static extern int GetWindowLong(IntPtr hWnd, int nIndex);
        [DllImport("user32")]
        public static extern int SetWindowLong(IntPtr hwnd, int nIndex, int dwNewLong);

        [StructLayout(LayoutKind.Sequential)]
        public struct WindowCompositionAttributeData
        {
            public WindowCompositionAttribute Attribute;
            public IntPtr Data;
            public int SizeOfData;
        }
        public enum WindowCompositionAttribute
        {
            WCA_UNDEFINED = 0,
            WCA_NCRENDERING_ENABLED = 1,
            WCA_NCRENDERING_POLICY = 2,
            WCA_TRANSITIONS_FORCEDISABLED = 3,
            WCA_ALLOW_NCPAINT = 4,
            WCA_CAPTION_BUTTON_BOUNDS = 5,
            WCA_NONCLIENT_RTL_LAYOUT = 6,
            WCA_FORCE_ICONIC_REPRESENTATION = 7,
            WCA_EXTENDED_FRAME_BOUNDS = 8,
            WCA_HAS_ICONIC_BITMAP = 9,
            WCA_THEME_ATTRIBUTES = 10,
            WCA_NCRENDERING_EXILED = 11,
            WCA_NCADORNMENTINFO = 12,
            WCA_EXCLUDED_FROM_LIVEPREVIEW = 13,
            WCA_VIDEO_OVERLAY_ACTIVE = 14,
            WCA_FORCE_ACTIVEWINDOW_APPEARANCE = 15,
            WCA_DISALLOW_PEEK = 16,
            WCA_CLOAK = 17,
            WCA_CLOAKED = 18,
            WCA_ACCENT_POLICY = 19,
            WCA_FREEZE_REPRESENTATION = 20,
            WCA_EVER_UNCLOAKED = 21,
            WCA_VISUAL_OWNER = 22,
            WCA_LAST = 23
        }
        public enum ACCENT_STATE
        {
            ACCENT_DISABLED = 0,
            ACCENT_ENABLE_GRADIENT = 1,
            ACCENT_ENABLE_TRANSPARENTGRADIENT = 2,
            ACCENT_ENABLE_BLURBEHIND = 3,
            ACCENT_ENABLE_ACRYLICBLURBEHIND = 4,
            ACCENT_INVALID_STATE = 5
        }
        [StructLayout(LayoutKind.Sequential)]
        public struct ACCENT_POLICY
        {
            public ACCENT_STATE AccentState;
            public int AccentFlags;
            public int GradientColor;
            public int AnimationId;
        }
        [DllImport("user32.dll")]
        public static extern int SetWindowCompositionAttribute(IntPtr hwnd, ref WindowCompositionAttributeData data);

        [DllImport("user32.dll")]
        public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
        
        //设置分层窗口的不透明度和透明度颜色键
        [DllImport("user32", EntryPoint = "SetLayeredWindowAttributes")]
        private static extern int SetLayeredWindowAttributes(IntPtr hwnd,int crKey,int bAlpha,int dwFlags
        );
        
                //设置窗口透明效果
        private void SetWindowTransparent(IntPtr hwnd,int Alpha)
        {
            //IntPtr hwnd = FindWindow(null,"...");
            int OldStyle = GetWindowLong(hwnd,GWL_EXSTYLE);
            SetWindowLong(hwnd,GWL_EXSTYLE, OldStyle | WS_EX_LAYERED);
            SetLayeredWindowAttributes(hwnd, Color.FromArgb(200, Color.Gray).ToArgb(), Alpha,LWA_ALPHA);
        }
        
        
                //设置窗口模糊效果
        private void SetWindowAero(IntPtr hwnd)
        {
                //IntPtr hWnd = FindWindow(null,"...");
                ACCENT_POLICY accent = new ACCENT_POLICY
                {
                    AccentState = ACCENT_STATE.ACCENT_ENABLE_BLURBEHIND,
                    AccentFlags = 0,
                    AnimationId = 0,
                    GradientColor = 0
                };
                var accentStructSize = Marshal.SizeOf(accent);
                var accentPtr = Marshal.AllocHGlobal(accentStructSize);
                Marshal.StructureToPtr(accent, accentPtr, false);
                WindowCompositionAttributeData data = new WindowCompositionAttributeData
                {
                    Attribute = WindowCompositionAttribute.WCA_ACCENT_POLICY,
                    Data = accentPtr,
                    SizeOfData = accentStructSize
                };
                SetWindowCompositionAttribute(hwnd, ref data);
                Marshal.FreeHGlobal(accentPtr);   
        }
         #endregion
      
		void Timer1Tick(object sender, EventArgs e)
		{
			string inipath=Directory.GetCurrentDirectory()+"\\setting.ini"; 
			iniHelper.Write("Topbar","backcolor",ColorTranslator.ToHtml(GetColorizationColor()),inipath); //获取主题颜色
			string color=iniHelper.Read("Topbar","backcolor",inipath);
			panel1.BackColor=ColorTranslator.FromHtml(color); 
		}
		void ExitToolStripMenuItemClick(object sender, EventArgs e)
		{
			this.Close();
			 Process[] processes = Process.GetProcesses();//获取所有进程信息
			for (int i = 0; i < processes.Length; i++)
			{
			    if (processes[i].ProcessName.ToLower() == "explorer")
			    {
			        try
			        {
			            processes[i].Kill(); //停止进程
			            return;
			        }
			        catch (Exception)
			        {
			            
			        }
			    }
			}
			Process.Start("explorer.exe");//再启动进程
		}
		 
		
		//***********************************
	}
}
